//=============================================================================
// EXECUTABLE 'SEEZERO'
//=============================================================================
// per Marc Delgado (marcdelgado@gmail.com) | rev. 2012.06.11

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include "utils.hpp"
using namespace std;

//VARIABLES GLOBALS I FUNCIONS
FILE* _file;        //Punter a fitxer del disc físic.
char* _buf;         //Punter a dades auxiliar.
//FUNCIONS AUXILIARS
void ajuda();           //Mostra l'ajuda d'aquesta aplicació.
void mostraMapa();      //Mostra el mapa de disponibilitat de pàgines.
void mostraFitxers();   //Mostra la llista de fitxer que hi ha al disc virtual.


//FUNCIO PRINCIPAL
///////////////////////////////////////////////////////////////////////////////


int main(int argc, char *argv[])
{
	if(argc==2){
		//Preparem l'arxiu i obtenim la mida
		_file = fopen(argv[1], "rb");
		//Calculem les pagines que te.
		fseek (_file, 0, SEEK_END);
		long int mida = ftell(_file) / 1024;
		fseek (_file, 0, SEEK_SET);
		//Comprobem que no demanem una pagina fora de rang
		if (mida >= 1024)
		{
            _buf = new char[1024];
			fread(_buf, 1, 1024, _file);
            cout << "=== OCCUPATION MAP / FILE LIST ======================================" << endl;
            mostraMapa();
            mostraFitxers();
            cout << "=====================================================================" << endl;
		}
		else cout << "ERROR: fitxer no valid." << endl;
	}
	else ajuda();
	//Tanquem l'arxiu
	fclose (_file);
}


//FUNCIONS AUXILIARS
///////////////////////////////////////////////////////////////////////////////


//Mostra informacio sobre els parametres d'execucio
void ajuda()
{
	cout << endl;
	cout << "FBDA Veure pagina zero - Parametre:" << endl;
	cout << "SeeZero [nom_disc]" << endl;

}


//Mostra el mapa de disponibilitat de pàgines.
void mostraMapa()
{
	cout << "---------------------------------------------------------------------" << endl;
	int n = 0; int count = 0;
	for (int i = 0; i < 512; i++)
	{
		byte val = _buf[i];
		for (int j = 0; j < 8; j++)
		{
		    if (val.getBit(j)){
		        count++;
		        n = (i*8)+j ;
		        if (n < 10) cout << " ";
		        if (n < 100) cout << " ";
		        if (n < 1000) cout << " ";
		        cout << n << " ";
                if (count >= 14){cout << endl; count = 0;}
		    }
		}
	}
	if (count != 0) cout << endl;
	cout << "---------------------------------------------------------------------" << endl;
}

void mostraFitxers()
{
	cout << "SLOT" << "\tNAME" << "\tNPAG" << "\tTYPE" << "\t\tSIZE REG." << "\tSIZE KEY" << endl;
	cout << "---------------------------------------------------------------------" << endl;
	for (int i = 520; i < 1024; i = i+12)
	{
	    if(_buf[i] != 0)
	    {
	        int slot = (i - 512)/12 + 1;
	        cout << " " << slot << "\t";
	        //Mostrem el NAME del fitxer.
	        string name = &_buf[i]; name.resize(6,NULL); cout << name << "\t";
	        //Mostrem NPAG (ojo! tenim els bytes invertits).
	        unsigned short npag; memcpy(&npag, &_buf[i+7] ,1); memcpy(&npag + 1, &_buf[i+6] ,1); cout << npag << "\t";
            //Mostrem el TYPE, en funció del codi de format.
            char type = _buf[i+8];
            if (type == 1) cout << "Heap    \t";
            else if (type == 2) cout << "Arbre B \t";
            else if (type == 3) cout << "Arbre B+\t";
            else if (type == 4) cout << "Hash Ext\t";
            else if (type == 5) cout << "Hash Lin\t";
            else cout << "????????\t";
            //Mostrem MR
            cout << (int)(unsigned char)(_buf[i+9]) << "\t\t";
            //Mostrem MCC
            cout << (int)(unsigned char)_buf[i+10];
	        cout << endl;
	    }
	}
}

